package com.qkun.library.utils;

import android.app.Activity;
import android.app.Application;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.qkun.library.base.BaseApplication;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public final class ActivityManager implements Application.ActivityLifecycleCallbacks {

    private final Stack<Activity> mActivityStack = new Stack<>();
    private final List<ActivityLifecycleCallback> mActivityLifecycleCallbacks = new ArrayList<>();

    private ActivityManager() {
    }

    /**
     * isFinishing() 用于判断 Activity 是否正在 finish
     * isDestroy() 用于判断 Activity 是否已经 destroy
     * isFinishing() 返回 true 后 isDestroy() 才会返回 true
     *
     * @param activity
     * @return
     */
    public static boolean isFinishing(Activity activity) {
        return Utils.isNull(activity) || activity.isFinishing();
    }

    /**
     * 判断一个activity是否存在于系统
     *
     * @param activityName
     * @return
     */
    public static boolean haveTheActivityInSystem(String packageName, String activityName) {
        if (!TextUtils.isEmpty(packageName) && !TextUtils.isEmpty(activityName)) {
            Intent intent = new Intent();
            intent.setClassName(packageName, activityName);
            return Utils.nonNull(intent.resolveActivity(BaseApplication.getAppContext().getPackageManager()));
        }
        return false;
    }

    public static ActivityManager getInstance() {
        return Holder.instance;
    }

    /**
     * 判断一个activity是否存在于系统
     *
     * @param activityName
     * @return
     */
    public static boolean isActivityExistInSystem(String activityName) {
        if (!TextUtils.isEmpty(activityName)) {
            Intent intent = new Intent();
            intent.setClassName(BaseApplication.getAppContext(), activityName);
            return Utils.nonNull(intent.resolveActivity(BaseApplication.getAppContext().getPackageManager()));
        }
        return false;
    }

    public void addActivityLifecycleCallback(ActivityLifecycleCallback callback) {
        mActivityLifecycleCallbacks.add(callback);
    }

    public void removeActivityLifecycleCallback(ActivityLifecycleCallback callback) {
        mActivityLifecycleCallbacks.remove(callback);
    }

    public void removeAllActivityLifecycleCallback() {
        mActivityLifecycleCallbacks.clear();
    }

    public void addActivity(Activity activity) {
        if (Utils.nonNull(activity)) {
            mActivityStack.add(activity);
        }
    }

    public void removeActivity(Activity activity) {
        if (Utils.nonNull(activity)) {
            mActivityStack.remove(activity);
        }
    }

    public Activity getActivity(Class<?> cls) {
        for (Activity activity : mActivityStack) {
            if (activity.getClass().equals(cls)) {
                return activity;
            }
        }
        return null;
    }

    public boolean isFinishing(Class<?> cls) {
        return isFinishing(getActivity(cls));
    }

    public Activity getTopActivity() {
        return mActivityStack.lastElement();
    }

    public Activity getBottomActivity() {
        return mActivityStack.firstElement();
    }

    public void finishActivity(Activity activity) {
        if (!isFinishing(activity)) {
            activity.finish();
        }
    }

    public void finishActivity(Class<?> cls) {
        finishActivity(getActivity(cls));
    }

    /**
     * 杀死该应用进程用 android.os.Process.killProcess(android.os.Process.myPid())
     * 调用 System.exit(n) 实际上等效于调用 Runtime.getRuntime().exit(n)，n通一般是0
     * finish() 是Activity的类方法，仅仅针对Activity
     * 当调用finish()时，只是将活动推向后台，并没有立即释放内存，活动的资源并没有被清理
     * 当调用System.exit(0)时，退出当前Activity并释放资源（内存），但并不可以结束整个App（如有多个Activity或者有其他组件service等不会结束）
     * 实际上android的机制决定了用户无法完全退出应用，当你的application在长时间没有被用过的时候，android自身会决定将application关闭了
     */
    public void finishAllActivity() {
        for (Activity activity : mActivityStack) {
            finishActivity(activity);
        }
    }

    public boolean haveActivityInCurrentStack() {
        return !mActivityStack.isEmpty();
    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        MyLog.v(activity.getLocalClassName());
        addActivity(activity);
        final int N = mActivityLifecycleCallbacks.size();
        for (int i = 0; i < N; i++) {
            mActivityLifecycleCallbacks.get(i).onActivityCreated(activity, savedInstanceState);
        }
    }

    @Override
    public void onActivityStarted(Activity activity) {
        MyLog.v(activity.getLocalClassName());
        final int N = mActivityLifecycleCallbacks.size();
        for (int i = 0; i < N; i++) {
            mActivityLifecycleCallbacks.get(i).onActivityStarted(activity);
        }
    }

    @Override
    public void onActivityResumed(Activity activity) {
        MyLog.v(activity.getLocalClassName());
        final int N = mActivityLifecycleCallbacks.size();
        for (int i = 0; i < N; i++) {
            mActivityLifecycleCallbacks.get(i).onActivityResumed(activity);
        }
    }

    @Override
    public void onActivityPaused(Activity activity) {
        MyLog.v(activity.getLocalClassName());
        final int N = mActivityLifecycleCallbacks.size();
        for (int i = 0; i < N; i++) {
            mActivityLifecycleCallbacks.get(i).onActivityPaused(activity);
        }
    }

    @Override
    public void onActivityStopped(Activity activity) {
        MyLog.v(activity.getLocalClassName());
        final int N = mActivityLifecycleCallbacks.size();
        for (int i = 0; i < N; i++) {
            mActivityLifecycleCallbacks.get(i).onActivityStopped(activity);
        }
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
        MyLog.v(activity.getLocalClassName());
        final int N = mActivityLifecycleCallbacks.size();
        for (int i = 0; i < N; i++) {
            mActivityLifecycleCallbacks.get(i).onActivitySaveInstanceState(activity, outState);
        }
    }

    @Override
    public void onActivityDestroyed(Activity activity) {
        MyLog.v(activity.getLocalClassName());
        final int N = mActivityLifecycleCallbacks.size();
        for (int i = 0; i < N; i++) {
            mActivityLifecycleCallbacks.get(i).onActivityDestroyed(activity);
        }
        removeActivity(activity);
        if (activity.isTaskRoot()) {
            ResultProcessor.clear();
        }
    }

    private static class Holder {
        private static final ActivityManager instance = new ActivityManager();
    }

    public static class ActivityLifecycleCallback implements Application.ActivityLifecycleCallbacks {

        @Override
        public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {

        }

        @Override
        public void onActivityStarted(@NonNull Activity activity) {

        }

        @Override
        public void onActivityResumed(@NonNull Activity activity) {

        }

        @Override
        public void onActivityPaused(@NonNull Activity activity) {

        }

        @Override
        public void onActivityStopped(@NonNull Activity activity) {

        }

        @Override
        public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {

        }

        @Override
        public void onActivityDestroyed(@NonNull Activity activity) {
            ActivityManager.getInstance().removeActivityLifecycleCallback(this);
        }
    }

}